异步编程 (Asynchronous Programming)
JavaScript 异步编程的核心概念与实现。
1. 串行执行 Async Tasks
使用 async/await 实现任务的串行执行。
javascript
async function runAsyncTasks(tasks) {
for (let task of tasks) {
await task();
}
}2. 手写 Promise (A+ 规范)
一个简易但核心逻辑完整的 Promise 实现,包含 resolvePromise 解决过程。
javascript
const PENDING = 'pending';
const FULFILLED = 'fulfilled';
const REJECTED = 'rejected';
class MyPromise {
constructor(executor) {
this.status = PENDING; // 状态
this.value = undefined; // 成功的值
this.reason = undefined; // 失败的原因
this.onResolvedCallbacks = []; // 存放成功的回调
this.onRejectedCallbacks = []; // 存放失败的回调
const resolve = (value) => {
// 如果 value 是 Promise,递归解析
if (value instanceof MyPromise) {
return value.then(resolve, reject);
}
if (this.status === PENDING) {
this.status = FULFILLED;
this.value = value;
this.onResolvedCallbacks.forEach(fn => fn());
}
};
const reject = (reason) => {
if (this.status === PENDING) {
this.status = REJECTED;
this.reason = reason;
this.onRejectedCallbacks.forEach(fn => fn());
}
};
try {
executor(resolve, reject);
} catch (e) {
reject(e);
}
}
// --- 核心 then 方法 ---
then(onFulfilled, onRejected) {
// 穿透处理:如果不是函数,直接返回原值
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v;
onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err; };
const promise2 = new MyPromise((resolve, reject) => {
if (this.status === FULFILLED) {
queueMicrotask(() => { // 模拟微任务
try {
let x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
});
} else if (this.status === REJECTED) {
queueMicrotask(() => {
try {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
});
} else if (this.status === PENDING) {
// 如果是异步,先订阅
this.onResolvedCallbacks.push(() => {
queueMicrotask(() => {
try {
let x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
});
});
this.onRejectedCallbacks.push(() => {
queueMicrotask(() => {
try {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
});
});
}
});
return promise2;
}
}
/**
* Promise 解决程序:处理 then 回调的返回值 x
*/
function resolvePromise(promise2, x, resolve, reject) {
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise'));
}
if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
let called = false;
try {
let then = x.then;
if (typeof then === 'function') {
then.call(x, y => {
if (called) return;
called = true;
resolvePromise(promise2, y, resolve, reject);
}, r => {
if (called) return;
called = true;
reject(r);
});
} else {
resolve(x);
}
} catch (e) {
if (called) return;
called = true;
reject(e);
}
} else {
resolve(x);
}
}3. SSE (Server-Sent Events) 演示
使用 Node.js (Express) 实现 SSE 服务端推送。
javascript
/* 服务端代码示例 (Node.js) */
const express = require('express');
const app = express();
app.get('/sse', (req, res) => {
// 设置 SSE 响应头
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
res.setHeader('Access-Control-Allow-Origin', '*');
// 每秒发送一次消息
const intervalId = setInterval(() => {
const message = `data: ${new Date().toLocaleTimeString()}\n\n`;
res.write(message);
}, 1000);
req.on('close', () => {
clearInterval(intervalId);
res.end();
});
});html
<!-- 客户端代码示例 -->
<div id="clock"></div>
<script>
const eventSource = new EventSource('/sse');
const clock = document.getElementById('clock');
eventSource.onmessage = function(event) {
clock.textContent = event.data;
};
</script>